package edu.ustb.efws.pipeline.service;

import edu.ustb.efws.EfwsProperties;
import edu.ustb.efws.base.domain.Detector;
import edu.ustb.efws.base.mapper.DetectorMapper;
import edu.ustb.efws.pipeline.domain.ThosLog;
import edu.ustb.efws.pipeline.mapper.ThosLogMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 温湿度传感器日志业务服务
 *
 * @author TS Group
 */
@Service
@Transactional(readOnly = true)
public class ThosLogService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ThosLogService.class);

    private final ThosLogMapper logMapper;
    private final DetectorMapper detectorMapper;
    private final TableOptService tableOptService;
    private final EfwsProperties properties;

    @Autowired
    public ThosLogService(ThosLogMapper logMapper, DetectorMapper detectorMapper,
                          EfwsProperties properties, TableOptService tableOptService) {

        this.logMapper = logMapper;
        this.detectorMapper = detectorMapper;
        this.tableOptService = tableOptService;
        this.properties = properties;
    }

    /**
     * 创建新的日志表，日志是按照月分割的
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void createTable(){
        try{
            for(Detector detector: getThoses()) {
                String tableName = buildTableName(detector.getTableName());
                tableOptService.createIfAbsent(tableName, e -> {
                    logMapper.createTable(detector.getTableName());
                    //创建分区
                    tableOptService.createPartition(e, properties.getStartMonth(),
                            (m, p) -> logMapper.createPartition(detector.getTableName(), m, p));
                });
            }
            createPartition();
        }catch (Exception e){
            LOGGER.error("Create thos log table fail error={}", e.getMessage());
        }
    }

    /**
     * 查询温湿度氧气传感器
     *
     * @return 温湿度氧气传感器
     */
    private List<Detector> getThoses(){
        return detectorMapper.findByType("温湿度氧气传感器");
    }

    /**
     * 创建日志表名
     *
     * @param tableName 表名
     * @return 表名
     */
    private String buildTableName(String tableName){
        return  String.format("zlg_%s", tableName);
    }

    /**
     * 创建分区
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void createPartition(){
        try{
            for(Detector detector: getThoses()) {
                String tableName = buildTableName(detector.getTableName());
                tableOptService.createPartition(tableName, properties.getStartMonth(),
                        (m, p) -> logMapper.createPartition(detector.getTableName(), m, p));
            }
        }catch (Exception e){
            LOGGER.error("Create thos log table partition fail error={}", e.getMessage());
        }
    }

    /**
     * 删除分区
     *
     * @param fromMonthNum 开始月份
     * @param toMonthNum 结束月份
     * @param remark 备注
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void dropPartition(int fromMonthNum, int toMonthNum, String remark){
        try{
            for(Detector detector: getThoses()) {
                tableOptService.dropPartition(detector.getTableName(), fromMonthNum, toMonthNum, remark,
                        p -> logMapper.dropPartition(detector.getTableName(), p));
            }
        }catch (Exception e){
            LOGGER.error("Drop thos log table partition fail error={}", e.getMessage());
        }
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void save(String tableName, List<ThosLog> logs){
        Map<String, Object> param = new HashMap<>(2, 1);
        param.put("tableName", tableName);
        param.put("logs", logs);
        logMapper.insertBatch(param);
    }
}
